home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
476-500
/
500
/
wiconify
/
wiconsetter.lzh
/
wIconSetter
/
Source
/
wIconHandler.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-19
|
11KB
|
453 lines
/*
* WICONSETTER A companion utility to wIconify. wIconSetter allows
* you to specify custom icons for windows ans screens
* that normally use the default icons.
*
* wIconHandler.c The main Handler code.
*
* Copyright 1990 by Davide P. Cervone, all rights reserved.
* You may use this code, provided this copyright notice is kept intact.
*/
#include "wIconHandler.h"
/*
* Variables and routines needed for traps via SetFunction()
*/
long OldOpenWindow;
long OldSetWindowTitles;
long OldOpenScreen;
extern void cOpenWindow();
extern void aOpenWindow();
extern void cSetWindowTitles();
extern void aSetWindowTitles();
extern void cOpenScreen();
extern void aOpenScreen();
/*
* Routines passed to the loader
*/
extern void GetProgramName();
extern int PrefixMatch();
extern ICONWINDOW *FindIcon();
extern WICONREF *wIconOf(); /* Part of wIconCalls.o */
static ICONPROGRAM *FirstProgram; /* The list of icons */
static ICONPROGRAM *ProgramAny; /* the special ANY program */
static ICONDEFINE *FirstDefine; /* the list of defined icons */
struct SysBase *SysBase;
static char *IconProcess = ICONPROCNAME; /* Our process name */
#define NOTICONIFY(p) (stricmp(p,IconProcess) != 0)
#define TOUPPER(c) (((c)>='a'&&(c)<='z')?(c)-'a'+'A':c)
#define MATCH(n1,n2) (stricmp(n1,n2))
#define PREFIXMATCH(n1,n2) ((n1) == NAME_ANY || PrefixMatch(n1,n2) == 0)
#define WPREFIXMATCH(n1,n2)\
(((n1) == NAME_ANY && (n2) != SCREENICON) || PrefixMatch(n1,n2) == 0)
/*
* IconHandlerData is passed to the loader on startup.
* It is used to pass values to the loader and receive initialized
* values from the loader.
*/
struct IconHandlerInfo IconHandlerData =
{
{ /* the MsgPort is pre-setup */
{NULL,NULL, NT_MSGPORT, 0, PORTNAME}, /* to include the name and */
PA_IGNORE, 0, NULL, /* type so that it can just */
{NULL,NULL,NULL, 0,0} /* be added to the port list */
}, /* so it can be found later */
MAJVERS,MINVERS, MINLOADVERS, /* version numbers */
NULL, /* the loaded segment code */
/*
* The libraries needed by the handler
*/
&IntuitionBase,
&SysBase,
/*
* The routines and variables trapped by the loader
*/
&aOpenWindow,
&OldOpenWindow,
&aSetWindowTitles,
&OldSetWindowTitles,
&aOpenScreen,
&OldOpenScreen,
/*
* Data needed by the loader
*/
&GetProgramName,
&PrefixMatch,
&FindIcon,
&FirstDefine,
&FirstProgram,
&ProgramAny,
};
/*
* Setup()
*
* This routine MUST be linked into the wIconSetter-Handler executable
* as the first routine, so that the loader can find it.
* It should check the version number for compatibility with the loader,
* and should return NULL for an error, or the pointer to the shared
* data structure if everything is OK.
*/
struct IconHandlerInfo *Setup(version)
int version;
{
if (version < MINLOADVERS) return(NULL);
return(&IconHandlerData);
}
/*
* PrefixMatch()
*
* Case-insensitive prefix match. NULL pointers and empty strings
* only match themselves, and are not considered prefixes to any string.
* The special SCREENICON value only matches itself.
*
* Return <0 if the first is smaller than the second,
* =0 if the first is a prefix of the second,
* >1 if the first is larger than the second.
*/
int PrefixMatch(s1,s2)
char *s1,*s2;
{
int match = -1;
if (s1 == SCREENICON || s2 == SCREENICON) match = (s1 == s2)? 0: 1;
else if (s1)
{
if (s2)
{
if (*s1)
{
while (TOUPPER(*s1) == TOUPPER(*s2) && *s2 != 0) s1++,s2++;
if (*s1 == 0) match = 0; else match = *s1 - *s2;
} else if (*s2 == 0) match = 0;
} else match = 1;
} else if (s2 == NULL) match = 0;
return(match);
}
/*
* FindIconWindow()
*
* Start with the first window of the given screen
* While there are more windows to look at
* If the window matches the name, return the window pointer
* Otherwise go on to the next one
* Return NULL if no match
*/
static ICONWINDOW *FindIconWindow(IScreen,Name)
ICONSCREEN *IScreen;
char *Name;
{
ICONWINDOW *IWindow = IScreen->Window;
while (IWindow)
{
if (WPREFIXMATCH(IWindow->Name,Name)) return(IWindow);
IWindow = IWindow->Next;
}
return(NULL);
}
/*
* FindIconScreen()
*
* While there are more screen to look at
* If the screen matches the name, return the screen pointer
* Otherwise go on to the next one
* Return NULL if no match
*/
static ICONSCREEN *FindIconScreen(IScreen,Name)
ICONSCREEN *IScreen;
char *Name;
{
while (IScreen)
{
if (PREFIXMATCH(IScreen->Name,Name)) return(IScreen);
IScreen = IScreen->Next;
}
return(NULL);
}
/*
* FindIconProgram()
*
* While there are more programs to look at
* If the program name is ANY, always match, otherwise
* compare the program against the given name
* If there was a match, return the program
* Otherwise move down to the next level of the tree
* Return ProgramAny if nothing else matched
*/
static ICONPROGRAM *FindIconProgram(IProgram,Name)
ICONPROGRAM *IProgram;
char *Name;
{
int result;
while (IProgram)
{
if (IProgram->Name == NAME_ANY) result = 0;
else result = MATCH(IProgram->Name,Name);
if (result == 0) return(IProgram); else
if (result < 0) IProgram = IProgram->Prev; else IProgram = IProgram->Next;
}
return(ProgramAny);
}
/*
* FindIcon()
*
* Find the program structure for the given program name
* If found,
* Look through the program's list of screens
* While there are more screens to check and we haven't found a window
* Find the next matching screen
* If found,
* Look for the window on that screen and go on to the next screen
* return the window (or NULL if none found)
*/
ICONWINDOW *FindIcon(Program,theScreen,wTitle)
char *Program;
struct Screen *theScreen;
char *wTitle;
{
ICONPROGRAM *IProgram;
ICONSCREEN *IScreen;
ICONWINDOW *IWindow = NULL;
IProgram = FindIconProgram(FirstProgram,Program);
if (IProgram)
{
IScreen = IProgram->Screen;
while (IScreen && IWindow == NULL)
{
IScreen = FindIconScreen(IScreen,theScreen->DefaultTitle);
if (IScreen)
IWindow = FindIconWindow(IScreen,wTitle),
IScreen = IScreen->Next;
}
}
return(IWindow);
}
/*
* StripPath()
*
* Start at the end of the string
* While there are more characters to look at,
* Get the preceding character
* If it is '/' or ':' cancel the loop, otherwise back up a character
* Clip the length of the name, if necessary
* Terminate the Name string
* Copy the name portion of the string into the Name buffer
*/
static void StripPath(Name,s,len)
char Name[MAXNAME];
char *s;
short len;
{
short i = 0;
char c;
s += len;
while (len)
{
c = *(s-1);
if (c == '/' || c == ':') len = 0;
else len--, s--, i++;
}
if (i >= MAXNAME) i = MAXNAME-1;
Name[i] = 0;
while (i--) Name[i] = s[i];
}
/*
* GetProgramName()
*
* If we have a task to look at,
* If the task is a process
* If the process has a task number and a CLI structure
* Get the CLI structure, and use its current command name and length
* If we haven't found the name yet,
* Get the name from the task structure, and find its length
* Strip the path portion off the name
* Otherwise clear the name buffer
*/
void GetProgramName(Name,theTask)
char Name[MAXNAME];
struct Process *theTask;
{
struct CommandLineInterface *theCLI;
char *s = NULL;
short len;
if (theTask)
{
if (theTask->pr_Task.tc_Node.ln_Type == NT_PROCESS)
{
if (theTask->pr_TaskNum && theTask->pr_CLI)
{
theCLI = (struct CommandLineInterface *)BADDR(theTask->pr_CLI);
if (theCLI->cli_CommandName)
s = (char *)(BADDR(theCLI->cli_CommandName)), len = *s++;
}
}
if (s == NULL)
{
s = theTask->pr_Task.tc_Node.ln_Name;
len = strlen(s);
}
StripPath(Name,s,len);
} else {
Name[0] = 0;
}
}
/*
* HandleWindow()
*
* Get the name of the current process
* If it is not the wIconify-Handler process
* Look through the icon list for the given program/screen/window
* If found
* Get a copy of the icon (so we can modify it)
* Remove the Autoiconify flag, if any (it is wIconSetter private)
* Get the current icon position (if it exists)
* Set the window to have the (modified) icon
* If the original icon had the AUTOICONIFY flag and we are supposed
* to do autoiconify, then iconify the window
*/
static void HandleWindow(theWindow,DoAuto)
struct Window *theWindow;
int DoAuto;
{
char Program[MAXNAME];
ICONWINDOW *theIcon;
WICON tmpIcon;
GetProgramName(Program,FindTask(NULL));
if (NOTICONIFY(Program))
{
theIcon = FindIcon(Program,theWindow->WScreen,theWindow->Title);
if (theIcon)
{
tmpIcon = theIcon->Icon;
tmpIcon.Flags &= ~WI_AUTOICONIFY;
wIconXY(wIconOf(theWindow),&(tmpIcon.x),&(tmpIcon.y));
wSetIcon(theWindow,&tmpIcon);
if ((theIcon->Icon.Flags & WI_AUTOICONIFY) && DoAuto)
wIconify(theWindow);
}
}
}
/*
* cOpenWindow()
*
* If the window openned successfully,
* Check to see if it needs an icon.
*/
void cOpenWindow(theWindow)
struct Window *theWindow;
{
if (theWindow) HandleWindow(theWindow,TRUE);
}
/*
* cSetWindowTitles()
*
* If a window is specified and it is getting a new title,
* Check if the window with the new title should get an icon.
*/
void cSetWindowTitles(theWindow,wTitle,sTitle)
struct Window *theWindow;
UBYTE *wTitle,*sTitle;
{
if (theWindow && wTitle != (UBYTE *)-ONE) HandleWindow(theWindow,FALSE);
}
/*
* cOpenScreen()
*
* If the screen has a window (ie, wIconify added its backdrop window
* to it already)
* Get the name of the current task
* If it is not the wIconify-Handler process itself
* Look through the icon list for this program/screen
* If it needs an icon
* Get a copy of the screen icon for modification
* Clear the AUTOICONIFY flag (it is wIconSetter private)
* Set the screen to have the given icon
* If the original icon has the AUTOICONIFY flag,
* Iconify the screen
*/
void cOpenScreen(theScreen)
struct Screen *theScreen;
{
char Program[MAXNAME];
ICONWINDOW *theIcon;
WICON tmpIcon;
if (theScreen && theScreen->FirstWindow)
{
GetProgramName(Program,FindTask(NULL));
if (NOTICONIFY(Program))
{
theIcon = FindIcon(Program,theScreen,SCREENICON);
if (theIcon)
{
tmpIcon = theIcon->Icon;
tmpIcon.Flags &= ~WI_AUTOICONIFY;
wSetScreenIcon(theScreen,&tmpIcon);
if ((theIcon->Icon.Flags & WI_AUTOICONIFY))
wIconifyScreen(theScreen);
}
}
}
}